import { validatenull } from "./validate";

/**
 * 判断数据类型
 */
export const getObjType = (obj: any) => {
  const toString = Object.prototype.toString;
  const map: {
    [key: string]: string;
  } = {
    "[object Boolean]": "boolean",
    "[object Number]": "number",
    "[object String]": "string",
    "[object Function]": "function",
    "[object Array]": "array",
    "[object Date]": "date",
    "[object RegExp]": "regExp",
    "[object Undefined]": "undefined",
    "[object Null]": "null",
    "[object Object]": "object",
  };
  if (obj instanceof Element) {
    return "element";
  }
  return map[toString.call(obj)];
};

/**
 * 对象深拷贝
 */
export const deepClone = (data: any) => {
  const type = getObjType(data);
  let obj: any;
  if (type === "array") {
    obj = [];
  } else if (type === "object") {
    obj = {};
  } else {
    // 不再具有下一层次
    return data;
  }
  if (type === "array") {
    for (let i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === "object") {
    for (const key in data) {
      obj[key] = deepClone(data[key]);
    }
  }
  return obj;
};

//数组转树结构数组
export function translateDataToTree(
  sNodes: string | any[],
  key: string,
  parentKey: string,
  childKey: string
) {
  let i, l;
  key = key || "id";
  parentKey = parentKey || "pId";
  childKey = childKey || "children";
  if (!key || key === "" || !sNodes) {
    return [];
  }
  if (Object.prototype.toString.call(sNodes) === "[object Array]") {
    const r: any = [];
    const tmpMap: any = [];
    for (i = 0, l = sNodes.length; i < l; i++) {
      tmpMap[sNodes[i][key]] = sNodes[i];
    }
    for (i = 0, l = sNodes.length; i < l; i++) {
      if (
        tmpMap[sNodes[i][parentKey]] &&
        sNodes[i][key] !== sNodes[i][parentKey]
      ) {
        if (!tmpMap[sNodes[i][parentKey]][childKey]) {
          tmpMap[sNodes[i][parentKey]][childKey] = [];
        }
        tmpMap[sNodes[i][parentKey]][childKey].push(sNodes[i]);
      } else {
        r.push(sNodes[i]);
      }
    }
    return r;
  }
  return [sNodes];
}

// 树形结构数据转单层数组形式
export function treeToTranslateData(nodes: string | any[]): any {
  let r: any = [];
  if (Array.isArray(nodes)) {
    for (let i = 0, l = nodes.length; i < l; i++) {
      r.push(nodes[i]); // 取每项数据放入一个新数组
      if (Array.isArray(nodes[i].children) && nodes[i].children.length > 0) {
        // 若存在children则递归调用，把数据拼接到新数组中，并且删除该children
        r = r.concat(treeToTranslateData(nodes[i].children));
      }
      delete nodes[i].children;
    }
  }
  return r;
}

/**
 * 根据字典的value显示label
 */
export const findValueInArray = (dic: any[], value: any) => {
  let result: any = "";
  if (validatenull(dic)) {
    return value;
  }
  if (
    typeof value === "string" ||
    typeof value === "number" ||
    typeof value === "boolean"
  ) {
    let index = 0;
    index = findIndexInArray(dic, value);
    if (index !== -1) {
      result = dic[index].label;
    } else {
      result = value;
    }
  } else if (value instanceof Array) {
    result = [];
    let index = 0;
    value.forEach((ele) => {
      index = findIndexInArray(dic, ele);
      if (index !== -1) {
        result.push(dic[index].label);
      } else {
        result.push(value);
      }
    });
    result = result.toString();
  }
  return result;
};

/**
 * 根据字典的value查找对应的index
 */
export const findIndexInArray = (
  dic: string | any[],
  value: string | number | boolean
) => {
  for (let i = 0; i < dic.length; i++) {
    if (dic[i].value === value) {
      return i;
    }
  }
  return -1;
};

// 表单序列化
export const serialize = (data: { [x: string]: any }) => {
  const list: string[] = [];
  Object.keys(data).forEach((ele) => {
    list.push(`${ele}=${data[ele]}`);
  });
  return list.join("&");
};

// 查找节点
export const treeFind = (tree: any, func: (arg0: any) => any) => {
  for (const data of tree) {
    if (func(data)) {
      return data;
    }
    if (data.children) {
      const res: any = treeFind(data.children, func);
      if (res) {
        return res;
      }
    }
  }
  return null;
};

// 查找节点路径
export const treeFindPath = (
  tree: any,
  func: (arg0: any) => any,
  path: Array<any> = []
) => {
  if (!tree) {
    return [];
  }
  for (const data of tree) {
    path.push(data);
    if (func(data)) {
      return path;
    }
    if (data.children) {
      const findChildren: any = treeFindPath(data.children, func, path);
      if (findChildren.length) {
        return findChildren;
      }
    }
    path.pop();
  }
  return [];
};

export const findMenuParent: any = (menus: any[], id: any, key = "name") => {
  const arr: any[] = [];
  // let parent: any = null;
  let self: any = null;
  function ergodic(arrs: any[], obj: any) {
    arrs.forEach((m) => {
      m.parent = obj;
      arr.push(m);
      if (m.children && m.children.length) {
        ergodic(m.children, m);
      }
    });
  }
  ergodic(deepClone(menus), null);
  arr.forEach((a) => {
    if (a[key] == id) {
      self = a;
      // parent = a.parent;
    }
  });
  return self;
};
